/**
 * @file platformAPI.h
 *
 * Provide the APIs that IOTgo needs.
 *
 * @date   
 * @copyright 
 * 
 * 
 * 
 * 
 * 
 */

#ifndef _PLATFORMAPI_H
#define _PLATFORMAPI_H

/**
 * @addtogroup platformAPI
 * @{
 */


#define PLATFORM_RTL8711 0
#define PLATFORM_ESP8266 1
#define PLATFORM_LINUX   2

#define PLATFORM PLATFORM_ESP8266

#include <stdint.h>

#if (PLATFORM == PLATFORM_RTL8711)
#include <cmsis_os.h>
#include <FreeRTOS.h>
#include <task.h>
#include <platform/platform_stdlib.h>
#include <platform_opts.h>
#include <wifi_conf.h>
#include <wifi_ind.h>
#include <wifi_util.h>
#include <lwip_netconf.h>
#include <lwip/sockets.h>
#include "lwip/netdb.h"
#include <flash_api.h>
#include <polarssl/config.h>
#include <polarssl/memory.h>
#include <polarssl/ssl.h>
#include <iotgo_user_type.h>
#include <stdint.h>

#elif (PLATFORM == PLATFORM_ESP8266)
#include "c_types.h"
#include "spi_flash.h"
#include "lwip/sockets.h"
#include "lwip/netdb.h"
#include "lwip/ip4_addr.h"
#include "esp_misc.h"
#include "esp_wifi.h"
#include "esp_libc.h"

#include "esp_softap.h"
#include "esp_sta.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "cJSON.h"
#include "esp8266/eagle_soc.h"
#include "esp8266/gpio_register.h"
#include "esp8266/pin_mux_register.h"
#include "c_types.h"
#include "gpio.h"


#elif (PLATFORM == PLATFORM_LINUX)
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <pthread.h>
#include <sched.h>
#include <string.h>

#include <cJSON.h>

#include <polarssl/config.h>
#include <polarssl/net.h>
#include <polarssl/ssl.h>
#include "polarssl/platform.h"


#else
#endif

/* string length*/
#define STRING_DEVICE_ID_LEN        12
#define STRING_DEVICE_MODEL_LEN     12 
#define STRING_API_KEY_LEN          40
#define STRING_ROM_VERSION_LEN      12
#define STRING_DSERVER_DOMAIN_LEN   32
#define STRING_LSERVER_IP_LEN       16
#define STRING_WIFI_SSID_LEN        64
#define STRING_WIFI_PASSWORD_LEN    32

/*
 * @name : getDeviceInfo
 * @desc : A deviceID is a 11-bit string.(include the '\0')\n
 *         For example "10000015b5"\n
 *         An APIkey is a 37-bit string.(include the '\0')\n
 *         For example "174f460f-430f-4dda-9064-de3cff77c189".\n
 *         This function is to COPY the device info to where
 *         the parameter pointers points to.\n
 *         Each parameter is a pointer to an array.\n
 *         Do not change the pointer itself.
 * @param : deviceId ,a pointer to a 11-bit array like deviceID[11].\n
 *          apikey ,A pointer to a 37-bit array like apikey[37].
 * @return : 0 if it succeeds, -1 if it fails.
 */
extern int8_t getDeviceInfo(uint8_t *deviceID,uint8_t *apikey);

/*
 * @name : getDeviceModel
 * @desc : A model is a 12-bit string.(include the '\0')\n
 *         For example "PSA_BTA_CN"\n
 *         This function is to COPY the device model to where
 *         the parameter pointers points to.\n
 *         The parameter is a pointer to an array.\n
 *         Do not change the pointer itself.
 * @param : model ,a pointer to a 12-bit array like modle[12].\n
 * @return : 0 if it succeeds, -1 if it fails.
 */
extern int8_t getDeviceModel(uint8_t *model);


/*
 * @name : getFWVersion
 * @desc : A rom version is a max-9-bit string.(include '\0')\n
 *         For example "10.12.01".\n
 *         This function is to COPY the version string to where 
 *         the input pointer points to.\n
 *         Do not change pointer itself.
 *         This iotgo level software does not contain a version.
 * @param : A pointer to a max-9-bit string.
 * @return : 0 if it succeeds, -1 if fails.
 */   
extern int8_t getFWVersion(uint8_t *version);

/*
 * @name : setDServerInfo
 * @desc : A distri-Server name is a domain name.\n
 *         It's a max-30-bit string.(include '\0')\n
 *         For example "cn-disp.coolkit.cc"\n
 *         An distri-Server port is a int32_t number.\n
 *         For example 443.\n
 *         This function is to COPY & store the Dserver info.
 *         Do not change pointer itself.
 * @param : server_name ,a pointer to a max-30-bit string.\n
 *          dserver_port ,an uint32_t number.
 * @return : 0 if it succeeds, -1 if fails.
 */   
extern int8_t setDServerInfo(uint8_t *server_name,uint32_t dserver_port);

/*
 * @name : getDServerName
 * @desc : A distri-Server name is a domain name.\n
 *         It's a max-30-bit string.(include '\0')\n
 *         For example "cn-disp.coolkit.cc"\n
 *         An distri-Server port is a int32_t number.\n
 *         For example 443.\n
 *         This function is to COPY the Dserver info to where
 *         the parameter pointers point to.
 *         Do not change pointer itself.
 * @param : server_name, a pointer to a max-30-bit array like server_name[30].\n
 *          server_port, a pointer to an uint32_t number.
 * @return : 0 if it succeeds, -1 if fails.
 */   
extern int8_t getDServerInfo(uint8_t *server_name,uint32_t *server_port);

/*
 * @name : setLServerInfo
 * @desc : A long-connected-Server name is an IP.\n
 *         It's a max-16-bit string.(include '\0')\n
 *         For example "192.168.101.101"\n
 *         A long-connected-Server port is a int32_t number.
 *         For example 443.\n
 *         This function is to COPY & store the input info.
 *         Do not change the pointer itself.
 * @param : server_name,  a pointer to a max-16-bit string.\n
 *          server_port, a int32_t number.
 * @return : 0 if it succeeds, -1 if fails.
 */   
extern int8_t setLServerInfo(uint8_t *server_name,uint32_t server_port);

/*
 * @name : getLServerInfo
 * @desc : A long-connected-Server name is an IP.\n
 *         It's a max-16-bit string.(include '\0')\n
 *         For example "192.168.101.101"\n
 *         A long-connected-Server port is a int32_t number.
 *         For example 443.\n
 *         This function is to COPY the Lserver info to where
 *         the input pointer points to.\n
 *         Do not change the pointer itself.
 * @param : server_name, a pointer to a max-16-bit array like server_name[16].\n
 *          server_port, a pointer to an uint32_t number.
 * @return : 0 if it succeeds, -1 if fails.
 */   
extern int8_t getLServerInfo(uint8_t *server_name,uint32_t *server_port);


/*
 * @name : setConnectWifiInfo
 * @desc : Store a Wifi AP SSID and password that can be connected later.
 * @param : connect_ssid, a pointer to a max-30-bit string.(include '\0')\n
 *          password, a pointer to a max-30-bit string.(include '\0')
 * @return : 0 if it succeeds, -1 if fails.
 */   
extern int8_t setConnectWifiInfo(uint8_t *connect_ssid, uint8_t *password);

/*
 * @name : getConnectWifiInfo
 * @desc : Get a Wifi AP SSID and password that can be connected later.\n
 *         This function is to COPY the info to where
 *         the input pointers point to.\n
 *         Do not change the pointer itself.
 * @param : connect_ssid, a pointer to a max-30-bit array like ssid[30].\n
 *          password, a pointer to a max-30-bit array like password[30].\n
 * @return : 0 if it succeeds, -1 if fails.
 */   
extern int8_t getConnectWifiInfo(uint8_t *connect_ssid, uint8_t *password);

/*
 * @name : setupWifiAP
 * @desc : Set a Wifi AP on device with the input SSID string.\n
 *         ***The AP has No password.***\n
 *         The input SSID is a 17-bit string.(include '\0').\n
 *         For example "ITEAD-10000015b5".\n
 *         APP will connect this Wifi AP.
 * @param : A pointer to a 17-bit array like ssid[17].\n
 * @return : 0 if it succeeds, -1 if fails.
 */
extern int8_t setupWifiAP(uint8_t *ssid);

/*
 * @name : connectToWifi
 * @desc : Connect to the Wifi AP with input SSID & password.\n
 *         The AP encryption type should be auto detected.\n
 * @param : connect_ssid , a max-30-bit string.(include '\0')\n
 *          password, a max-30-bit string.(include '\0')\n
 * @return : 0 if it succeeds, -1 if fails.
 */
extern int8_t connectToWifi(uint8_t *connect_ssid,uint8_t *password);

/*
 * @name : getTimeStamp
 * @desc : This function is to get the linux system time stamp.\n
 *         The linux time stamp is a int32_t number.
 * @param :
 *         
 * @return : the time stamp
 */
extern int32_t getTimeStamp(void);

/*
 * @name : systemDelayMs
 * @desc : Provide an appropriate way to do delay in the system.\n

 * @param : ms, millisecond.
 * @return : 
 */
extern void systemDelayMs(uint32_t ms);

/*
 * @name : osGetRandom
 * @desc : Provide an appropriate way to get a random value in the system.\n

 * @param : void
 * @return : 
 */
extern int32_t osGetRandom(void);
/*
 * @name : setStatusLed
 * @desc : This function is used to turn on/off the status-led function.
 * @param : led_status , 0 == function off. (Not led off)
 *                       1 == function on. (Not led on)
 * @return : 0 if it succeeds, -1 if it fails.
 */
extern int8_t setStatusLed(uint8_t led_status);
/*
 * @name : getStatusLed
 * @desc : This function is used to get status-led's state.
 * @param : none     
 * @return : 0 == led_function_off\n 
 *           1 == led_function_on\n
 *          -1 == operation fails.
 */
extern int8_t getStatusLed(void);

/*
 * @name : setOtaInfo
 * @desc : This function is only used to update the OTA information.
 *         NOTE that DO NOT excute the OTA process in this function.
 *         The OTA should be excuted sometime after this function is done. 
 * @param : url ,a 125-bit string store the downloud path of the OTA bin file.
 *          digest , a 65-bit string. This is the result of sha256(bin)
 *          sequence, a 14-bit string & only needs to be update after OTA is done.
 *          This sequence needs to be passed to iotgoUpdateOtaDone(unsigned char *sequence).
 *          Do not change the point itself in this function.
 *          
 * @return : 0 if it succeeds, -1 if it fails.
 */
extern int8_t setOtaInfo(uint8_t *url, uint8_t *digest ,uint8_t *sequence);

/*
 * @name : getWifiRssi
 * @desc : get the wifi rssi from the platform.\n
 * @param : none
 * @return : rssi num if it succeeds, -1 if it fails.
 */   
extern int8_t getWifiRssi(void);



#endif
